3

前言

项目中遇到需要选取照片上传的需求,因为网页运行在微信的浏览器里面,所以想到了用微信的 js-sdk 提供的选取照片功能,来优化用户体验。

实现过程

1、选取照片

这里使用微信 js-sdk 的 chooseImage 方法,得到照片在本地存储的 id,十分简单:

wx.chooseImage({
  count: 1, 
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success: function (res) {
    var localId = res.localIds[0];
  }
)};

2、获取照片数据

主要是获取照片 base64 格式的数据用于上传,但是过程比较曲折,先后尝试了两种方法。

尝试一:设置 img 元素的 src 属性

根据微信的官方开发文档,得到的 localId 可以直接作为 img 元素的 src 属性进行显示,因此首先想到的是在 imgload 事件中构造 canvas,然后获取数据:

$('img.avatar-temp').on('load', function (e) {
  var image = e.target;
  var canvas = document.createElement('canvas');
  canvas.width = image.width;
  canvas.height = image.height;
  canvas.getContext('2d').drawImage(image);
  
  var dataUrl = canvas.toDataURL();
});

wx.chooseImage({
  count: 1, 
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success: function (res) {
    var localId = res.localIds[0];
    $('img.avatar-temp').attr('src', localId);
  }
)};

然而不幸的是,将 localId 设置进 src 之后,图片能显示,也没有报错,但是就是死活不触发 load 事件,也查不到是什么原因,因而此方案行不通。

尝试二:调用 js-sdk 的 getLocalImgData 方法

再次查阅文档,得知还有 getLocalImgData 用于获取本地图片数据,果断尝试:

wx.chooseImage({
  count: 1, 
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success: function (res) {
    var localId = res.localIds[0];
    wx.getLocalImgData({
      localId: localId,
      success: function (res) {
        var localData = res.localData;
      }
    )};
  }
)};

如上,得到的 localData 即为选取照片的 base64 格式的数据。这里有两个地方需要注意的:
1、iOS 系统里面得到的数据,类型为 image/jgp,不知道是 bug 还是什么原因,因此需要替换一下:

localData = localData.replace('jgp', 'jpeg');

2、安卓系统得到的数据,是没有 data:image/jpeg;base64, 前缀的。

3、上传照片

上传照片采用 FormData API 构造表单数据的办法,在我的另一篇文章有讨论过,此处不再赘述。


陈某
77 声望9 粉丝